home *** CD-ROM | disk | FTP | other *** search
/ Shareware Overload Trio 2 / Shareware Overload Trio Volume 2 (Chestnut CD-ROM).ISO / dir24 / aprs60.zip / MAPFIX.BAS < prev    next >
BASIC Source File  |  1994-09-30  |  57KB  |  1,246 lines

  1. REM MAPFIX.bas PROGRAM.  SEE EXPLAINATION BELOW
  2. REM
  3. Ver$ = "6.0": REM This version properly displays cursor loc in E long
  4.               REM and recovers from DISK NOT READY ERROR
  5. MaxNumMAPS = 120'was 99 Current maximum number of maps loaded by APRS
  6. MaxNumPoints = 1500 'was 1000
  7. MaxNumLABELS = 99 'was 99
  8. MaxNumLines = 900
  9. REM $DYNAMIC
  10. GOTO BEGIN
  11.  
  12. Info: COLOR 15, 4: CLS
  13.    PRINT " MAPFIX.bas VERSION "; Ver$; " PROGRAM FOR FIXING APRS MAPS": PRINT
  14.    PRINT " This program is always evolving.  Check the version number and HELP screen to"
  15.    PRINT " see whats new."
  16.    PRINT
  17.    PRINT " MAPFIX can build a map from the 2,000,000:1 USGS CD ROM, BUT NOT EASILY!  For"
  18.    PRINT " a 50 mile map, 5 MBytes of redundant USGS data must be filtered down to the"
  19.    PRINT " nominal 15K APRS size for the same area and same detail!  The final steps are"
  20.    PRINT " all manual and take almost as long as developing an APRS map from scratch!"
  21.    PRINT
  22.    PRINT " CAUTION, THIS PROGRAM IS NOT PERFECT... KEEP BACKUPS!  Do a little at a time!"
  23.    PRINT
  24.    PRINT " Although MAPFIX has commands to make map modifications easier, a text EDITOR is"
  25.    PRINT " still useful for whole scale rearranging of points and features in a map file. "
  26.    PRINT
  27.    PRINT " MAPFIX uses two cursors.  The normal yellow APRS cursor, and a White MapPoint"
  28.    PRINT " which will be the next point to be processed.  ALT Keys allow you to MOVE the"
  29.    PRINT " MapPoint to the cursor, ADD a new point at the cursor, or DELETE the MapPoint."
  30.    PRINT " The G command will GO your cursor and screen to the MapPoint and conversly,"
  31.    PRINT " the Find command will move the MapPoint to the feature nearest the cursor."
  32.    PRINT
  33.    PRINT " MAPFIX.bas shows you Deg/Min, Decimal, and APRS values of the cursor position."
  34.    PRINT
  35.    PRINT " ALSO NOTE THAT THE LIMITS IN APRS ARE 1500 POINTS, 99 FEATURES, and 99 LABELS!"
  36.    PRINT " If you need more points, features or labels, begin another map.";
  37.    LOCATE 25, 1: PRINT " HIT ANY KEY to continue...";
  38.    GOSUB GetChar: SOUND 800, 3
  39.   
  40. Info2:   COLOR 15, 8: CLS
  41.    PRINT " PAGE 2 INSTRUCTIONS:  More about new features in version "; Ver$
  42.    PRINT
  43.    PRINT " With MAPFIX.bas, you can modify features by moving, adding or deleting POINTS"
  44.    PRINT " or Killing whole features, ie: roads, rivers, borders, etc.  The TRIM command"
  45.    PRINT " will remove all points outside of the white box showing the MAP size formed"
  46.    PRINT " with the alt-Center and alt-Range commands."
  47.    PRINT
  48.    PRINT " If the MapPointer and FeatureName get out of sequence, the RESET command may"
  49.    PRINT " fix them, but you should save the file immediately and check it with an editor."
  50.    PRINT
  51.    PRINT " I find the capability to delete points very useful when making larger area"
  52.    PRINT " maps from several smaller detail maps.  First, I run MAPCNVRT.bas to convert"
  53.    PRINT " all of the smaller maps to new temporary files with the new origin of the new"
  54.    PRINT " larger map.  Then I use the KILL command in MAPFIX to eliminate all minor "
  55.    PRINT " roads, features and labels and then the DELETE POINT command to remove all"
  56.    PRINT " inconsequential minor points from the roads that will not be needed"
  57.    PRINT " at the larger scale.  Then I use the editor to combine all of the points and"
  58.    PRINT " labels into the new file."
  59.    PRINT
  60.    PRINT " A new MAPLIST command shows your MAPLIST.map file; and the OTHER MAPS command"
  61.    PRINT " shows all MAP borders so you can see how your new map fits in.  You may use F3"
  62.    PRINT " and F4 keys to select smaller or larger map borders to draw."
  63.    PRINT
  64.    LOCATE 25, 1: PRINT " HIT ANY KEY to continue...";
  65.    GOSUB GetChar: SOUND 800, 3
  66.   
  67. Info3:   COLOR 15, 3: CLS
  68.    PRINT " PAGE 3 INSTRUCTIONS:  Using GPS Track History Files to draw maps!"
  69.    PRINT
  70.    PRINT " To aid in creating accurate maps, W7KKE in California added routines to MAPFIX"
  71.    PRINT " so that you can overlay a Track History file onto the map you are constructing."
  72.    PRINT " This is an excellent tool for correcting your maps to real GPS data."
  73.    PRINT ""
  74.    PRINT " After you have loaded your map, type alt-G (GPS Track History') and enter the"
  75.    PRINT " history filename.  This will overlay the track history file.  You may then"
  76.    PRINT " use the normal MAPFIX.bas routines to move map segments and add so that the"
  77.    PRINT " map will agree with the GPS data contained in the track history file.  This"
  78.    PRINT " is especially useful with the history files saved by a laptop during mobile"
  79.    PRINT " GPS operations."
  80.    PRINT
  81.    PRINT " CAUTION:  Since GPS data is only accurate to 100 yards due to the effects of"
  82.    PRINT " Selective Availability, I would avoid using GPS data explicitely below about"
  83.    PRINT " the 2 mile range.  For this reason, I make the size of the GPS positions "
  84.    PRINT " expand below the 2 mile range to roughly approximate the size of the 100 yard"
  85.    PRINT " error circle."
  86.    PRINT
  87.    PRINT " Also note that you can now START a NEW map from scratch, without using the"
  88.    PRINT " text editor to enter the initial configuration data.  Just type NEW instread "
  89.    PRINT " of a MAPfilename when starting up the program."
  90.    LOCATE 25, 1: PRINT " HIT ANY KEY to continue...";
  91.    GOSUB GetChar: SOUND 800, 3
  92.  
  93.  
  94. Info4:   COLOR 15, 7: CLS
  95.    PRINT " PAGE 4 INSTRUCTIONS FOR USING A DIGITIZER:": PRINT
  96.    PRINT " In version 3.07B, MAPFIX.bas can now interface to a digitizer tablet or table"
  97.    PRINT " so that maps can be drawn directly from paper maps.  These routines were"
  98.    PRINT " developed by W7KKE and added to MAPFIX.bas in December 1993."
  99.    PRINT
  100.    PRINT " To use a digitizer, first you must hit the ALT-O command to open the COMM"
  101.    PRINT " PORT for the digitizer.  This command also lets you test the digitizer while"
  102.    PRINT " testing the alignment of the map on the digitizer surface.  It then prompts"
  103.    PRINT " you to identify the upper left and lower right corners of the map, in order"
  104.    PRINT " to calibrate the digitizer to the latitude, longitude and scale of the map."
  105.    PRINT
  106.    PRINT " From this point on, the button on the digitizer mouse is almost identical to"
  107.    PRINT " the ALT-A command for ADDing a point.  To start a new map feature, however,"
  108.    PRINT " for the digitizer, you DO NOT use the ALT-N NEW command, but you should use"
  109.    PRINT " the ALT-B BEGIN command.  For More information, see the README.DIG file."
  110.    PRINT
  111.    PRINT " To speed up the map drawing during editing, I no longer erase and re-draw"
  112.    PRINT " the entire map with each new point.  I simply draw just the new line segment."
  113.    PRINT " Sometimes, especially when you move, or add a line, this leaves an old line"
  114.    PRINT " segment, where there actually is no longer a line.  You can always celan up"
  115.    PRINT " the map by just hitting the space bar to force a new map..."
  116.    PRINT
  117.  
  118.   
  119.    Display$ = "UNKnown"
  120.    RETURN
  121.  
  122. GetChar: a$ = "": DO UNTIL a$ <> "": a$ = INKEY$: LOOP: RETURN
  123.  
  124. BEGIN: GOSUB Info:
  125.    PRINT " HIT ANY KEY to proceed onto the HELP screen...";
  126.    GOSUB GetChar
  127.  
  128.    DIM x%(5 * MaxNumPoints), y%(5 * MaxNumPoints)
  129.    REM MAP coordinates               **** THESE ARE BIGGER THAN APRS ***
  130.    DIM LN$(MaxNumLines) ' (no limit in APRS)  **** SO YOU CAN MANIPULATE BIG MAPS
  131.    nn = 2 * MaxNumLABELS
  132.    DIM ML$(nn), MLa(nn), MLo(nn), MLr(nn) 'Map Labels, lengths and coordinates
  133.    nn = 2 * MaxNumMAPS
  134.    DIM MapName$(nn), LATcen(nn), LONcen(nn), MapMax(nn), Comment$(nn)
  135.    RdsOn = -1: Labls = -1: Tags = -1: KP = 1: Changed = 0: MapSize = 256
  136.    i = 1000
  137.    DIM HLAT(i), HLONG(i)'For lat/longs from big GPS history files
  138.  
  139. INIT: ON ERROR GOTO ErrorTrap
  140.    ScrnType$ = "EGA": Ycen = 200: Yfactr = 1: YfacTXT = 350 / 350: SCREEN 9
  141.    IF ScrnType$ = "EGA" THEN COLOR 15, 0
  142.    REM ScrnType$ = "CGA": Yfactr=200/400:Ycen = 200*Yfactr: SCREEN 2
  143.    ReDraw = -1
  144.   
  145. Display$ = "HELP": GOSUB HELP: GOSUB LoadMap
  146. REM ON ERROR GOTO 0
  147.  
  148. Main: GOSUB DrwMPaCur
  149.   DO
  150. GoAgain: Fault = 0
  151.     IF Digitizer THEN
  152.          IF LOC(1) > 9 THEN
  153.             GOSUB GetXY: GOSUB Cursor
  154.             IF Btn <> 3 THEN GOSUB AddPoint
  155.          END IF
  156.     END IF
  157.     a$ = INKEY$
  158.     IF a$ <> "" THEN
  159.         a$ = UCASE$(a$): Key$ = a$
  160.         IF a$ = "S" THEN GOSUB labels
  161.         IF a$ = "L" THEN Labls = NOT Labls
  162.         IF a$ = "T" THEN Tags = NOT Tags
  163.         IF a$ = "F" THEN LnStrt = 0: StrtSrch = 1: GOSUB FindPoint
  164.         IF a$ = CHR$(6) THEN LnStrt = LnPtr: StrtSrch = Z + 1: GOSUB FindPoint
  165.         IF a$ = "G" THEN GOSUB CurToPoint: GOSUB CurDrwMap
  166.         IF a$ = "H" THEN
  167.            IF Display$ <> "HELP" THEN
  168.               GOSUB HELP
  169.            ELSE GOSUB Info
  170.               LOCATE 25, 1: PRINT " H for HELP or SPACE BAR for map..."; : a$ = ""
  171.            END IF
  172.         END IF
  173.         IF a$ = "B" THEN GOSUB BoxPPD
  174.         IF a$ = "U" THEN GOSUB GetUSGS
  175.         IF a$ = "D" THEN GOSUB MapDIR
  176.         IF a$ = "M" THEN GOSUB ListMAPlist
  177.         IF a$ = "O" THEN GOSUB DrwAndShow
  178.         IF a$ = "N" THEN GOSUB NextLine: GOSUB Cursor
  179.         IF a$ = "P" THEN GOSUB Previous: GOSUB Cursor
  180.         IF a$ = "Q" THEN GOSUB QUIT
  181.         IF a$ = "R" THEN Z = 2: LnPtr = 1
  182.         IF a$ = "T" THEN GOSUB Scrunch
  183.         IF a$ = " " THEN Display$ = "MAP": ReDraw = -1: USGS = 0: GOSUB DrwMPaCur
  184.         IF a$ = "+" THEN Z = Z + 1: GOSUB MapPoint ' moves to next map point
  185.         IF a$ = "-" THEN Z = Z - 1: GOSUB MapPoint ' moves backwards
  186.         IF a$ = CHR$(18) THEN ReDraw = NOT ReDraw: GOSUB ReDraw
  187.        
  188.         B$ = "": IF LEN(a$) = 2 THEN B$ = RIGHT$(a$, 1): REM process arrow & special keys
  189.         IF B$ = "I" THEN RS = RS * 2: GOSUB CurDrwMap: REM change scale
  190.         IF B$ = "Q" THEN RS = RS / 2: GOSUB CurDrwMap
  191.         IF B$ = CHR$(132) THEN RS = RS * 8: GOSUB CurDrwMap: REM change scale by factor of 4
  192.         IF B$ = "V" THEN RS = RS / 8: GOSUB CurDrwMap
  193.         IF B$ = "G" THEN GOSUB CurDrwMap 'Home key
  194.         IF a$ = "7" THEN CDX = LONo: CDY = LATo: GOSUB DrwMPaCur 'ShiftHOME
  195.         IF B$ = "O" THEN CDX = LONcen: CDY = LATcen: GOSUB DrwMPaCur 'End Key
  196.         IF B$ = "M" THEN CPX = CPX - 4 / (Sfac): GOSUB Cursor
  197.         IF B$ = "K" THEN CPX = CPX + 4 / (Sfac): GOSUB Cursor
  198.         IF B$ = "H" THEN CPY = CPY + 4 / (Sfac): GOSUB Cursor
  199.         IF B$ = "P" THEN CPY = CPY - 4 / (Sfac): GOSUB Cursor
  200.         REM Here are the special MapFIx routines
  201.         IF B$ = CHR$(30) THEN GOSUB AddPoint               'alt-ADD point
  202.         IF B$ = CHR$(48) AND Digitizer THEN GOSUB NewFeature'alt-BEGIN
  203.         IF B$ = CHR$(34) THEN GOSUB LoadHst                'alt-GPS hstry file
  204.         IF B$ = CHR$(50) THEN GOSUB MakePT: IF ReDraw THEN GOSUB DrawMap 'MOVE point to cursor
  205.         IF B$ = CHR$(32) THEN GOSUB DelPT                  'alt-DELete point
  206.         IF B$ = CHR$(38) THEN GOSUB AddLabel               'alt-ADD LABEL
  207.         IF B$ = CHR$(46) THEN GOSUB NewCenter              'alt-CENTER
  208.         IF B$ = CHR$(36) THEN GOSUB Join                   'alt-JOIN
  209.         IF B$ = CHR$(37) THEN GOSUB KillF                  'alt-KILL Feature
  210.         IF B$ = CHR$(19) THEN GOSUB MapRange               'alt-RANGE
  211.         IF B$ = CHR$(20) THEN GOSUB TRIM                   'alt-TRIM
  212.         IF B$ = CHR$(49) THEN GOSUB NewFeature             'alt-NEW Feature
  213.         IF B$ = CHR$(24) THEN GOSUB DigiInit: GOSUB DrawMap'alt-OPEN dgtzr COM
  214.         IF B$ = CHR$(31) THEN GOSUB Scrunch                'alt-SCRUNCH
  215.         IF B$ = CHR$(22) THEN GOSUB GetUSGS                'alt-U
  216.         IF B$ = CHR$(61) THEN                              'F3 for smaller Maps
  217.            MapSize = MapSize / 2: IF MapSize < 1 THEN MapSize = 1
  218.            GOSUB ShowMaps
  219.            END IF
  220.         IF B$ = CHR$(62) THEN                              'F4 for larger Maps
  221.            MapSize = MapSize * 2: IF MapSize > 1000 THEN MapSize = 1000
  222.            GOSUB DrwAndShow
  223.         END IF
  224.         IF a$ = CHR$(19) THEN GOSUB SaveMap
  225.         IF a$ = CHR$(3) THEN GOSUB ChgColr
  226.            
  227.         IF a$ = "6" THEN CPX = CPX - 20 / (Sfac): GOSUB Cursor'SHIFT Cursor by 4
  228.         IF a$ = "4" THEN CPX = CPX + 20 / (Sfac): GOSUB Cursor
  229.         IF a$ = "8" THEN CPY = CPY + 20 / (Sfac): GOSUB Cursor
  230.         IF a$ = "2" THEN CPY = CPY - 20 / (Sfac): GOSUB Cursor
  231.         
  232.     END IF
  233.   LOOP
  234.   SYSTEM 'you should never get here
  235.  
  236. ReDraw: LOCATE 1, 30
  237.         IF ReDraw THEN PRINT "REDRAW ENABLED":  ELSE PRINT "NO ReDraw...  "
  238.         RETURN
  239.  
  240. QUIT: a$ = "Y"
  241.       IF Changed THEN
  242.          GOSUB BoxLine23
  243.          PRINT "**** MAP HAS BEEN MODIFIED"; Changed; "TIMES BUT NOT SAVED!!!  SAVE NOW? (Y)";
  244.          INPUT a$
  245.       IF UCASE$(a$) <> "N" THEN GOSUB SaveMap
  246.       END IF
  247.       SYSTEM
  248.  
  249. TRIM: GOSUB BoxLine23
  250.       CLS : PRINT "TRIM ALL POINTS AND LABELS OUTSIDE OF MAPRANGE"
  251.       PRINT
  252.       PRINT "This command will remove all points and labels that are outside of the white"
  253.       PRINT "map border.  You can change the location of this map border by using"
  254.       PRINT "the CENTER command (alt-C) and by changing the RANGE using alt-R."
  255.       PRINT : PRINT
  256.       PRINT "No map feature will be completely eliminated..."
  257.       PRINT
  258.       PRINT "The first and last point of any FEATURE will be retained, so the"
  259.       PRINT "result will be long single lines for all FEATURES outside the map border."
  260.       PRINT "Use the KILL FEATURE (alt-K) to eliminate those lines and use the MOVE"
  261.       PRINT "command (alt-M) to move any far away points closer to the border."
  262.       PRINT : PRINT
  263.       PRINT "You might consider stopping now and doing a SAVE (ctrl-S) before proceeding."
  264.       PRINT
  265.       PRINT "ALSO, THIS DOES NOT WORK FOR POINTS WITH NEGATIVE VALUES!  Be sure  your"
  266.       PRINT "selected area is below and to right of ORIGIN.  If not, run MAPCNVRT.bas."
  267.       PRINT : PRINT
  268.       INPUT "Are you ready to proceed? (Y/N) (N)"; ans$
  269.       GOSUB DrawMap
  270.       IF UCASE$(ans$) <> "Y" THEN RETURN
  271.       C = 0: LOCATE 23, 1: PRINT "Processing...";
  272.       REM dx and dy are num pix of center of map
  273.       REM bx and by are borders of map based on MapRng
  274.       by = ppdV * MapRng / 60
  275.       bx = by / Lfac
  276.       FOR Z = 1 TO nmp - 4
  277.          IF x%(Z) = 0 THEN Z = Z + 2
  278.          IF x%(Z) > dx + bx OR y%(Z) > dy + by THEN bad = 1 ELSE bad = 0
  279.          IF x%(Z) < dx - bx OR y%(Z) < dy - by THEN bad = 1
  280.          IF bad AND x%(Z - 1) <> 0 AND x%(Z + 1) <> 0 THEN
  281.             GOSUB DelPT: Z = Z - 1
  282.             C = C + 1
  283.          END IF
  284.       NEXT Z
  285.       LOCATE 23, 1: PRINT "Now removing labels...";
  286.       FOR i = 1 TO nml: REM now eliminate all labels outside
  287.           bad = 0: Xm = MapRng / (60 * Lfac): Ym = MapRng / 60
  288.           IF MLo(i) > LONcen + Xm OR MLa(i) > LATcen + Ym THEN bad = 1
  289.           IF MLo(i) < LONcen - Xm OR MLa(i) < LATcen - Ym THEN bad = 1
  290.           IF bad = 1 THEN
  291.              FOR j = i TO nml
  292.                  ML$(j) = ML$(j + 1): MLa(j) = MLa(j + 1)
  293.                  MLo(j) = MLo(j + 1): MLr(j) = MLr(j + 1)
  294.              NEXT j: nml = nml - 1: PRINT ".";
  295.           END IF
  296.       NEXT i
  297.       GOTO DrawMap
  298.  
  299.  
  300. FindPoint: CurX = INT(.5 + dx + (CUX - 320) / (KP * Hfac))
  301.            CurY = INT(.5 + dy + (CUY - Ycen) / KP)
  302.  
  303.      GOSUB BoxLine23: PRINT "SEARCHING THROUGH ALL POINTS IN FILE...";
  304.      REM SaveZ = Z: SaveLNptr = LnPtr
  305. Agn: FOR j = 0 TO 30            ' Go through abt 20 times lookin pt.
  306.         IF j > 10 THEN j = j + 1' first with 0 delta, then bigger
  307.         PRINT ".";
  308.         LnCtr = LnStrt
  309.         FOR i = StrtSrch TO nmp
  310.             IF x%(i) = 0 THEN LnCtr = LnCtr + 1
  311.             IF x%(i) > CurX - j AND x%(i) < CurX + j THEN
  312.                IF y%(i) > CurY - j AND y%(i) < CurY + j THEN
  313.                   Z = i: LnPtr = LnCtr: GOSUB CurToPoint
  314.                   j = 99: i = nmp
  315.                END IF
  316.             END IF
  317.         NEXT i:
  318.     NEXT j
  319.     IF j < 99 AND Key$ = CHR$(6) THEN StrtSrch = 2: LnCtr = 1: Key$ = "F": GOTO Agn
  320.     IF j < 99 THEN PRINT "None found!": RETURN
  321.     GOSUB MapPoint: SavClr = 0: RETURN
  322.                   
  323. NewFeature: LOCATE 24, 1: PRINT SPACE$(27); : GOSUB BoxLine23
  324.             INPUT "Enter reference name for new feature"; a$
  325.             IF a$ = "" THEN RETURN
  326.             GOSUB Rainbow: IF abort THEN RETURN
  327.             GOSUB BeginF
  328.             GOSUB BoxLine23: LOCATE 25, 1: PRINT SPACE$(80); : LOCATE 25, 1
  329.             IF RIGHT$(Key$, 1) = CHR$(48) THEN
  330.                PRINT "NOW USE DIGITIZER TO ADD NEW POINTS TO THIS FEATURE...";
  331.                GOSUB GetXY: GOSUB Cursor
  332.             ELSE
  333.                PRINT "NOW MOVE CURSOR AND USE ALT-A TO ADD POINTS TO THIS NEW FEATURE...";
  334.             END IF
  335.             GOSUB MakePT
  336.             RETURN
  337.  
  338. Rainbow: LOCATE 25, 1
  339.          FOR i = 0 TO 14
  340.              PRINT RIGHT$(" " + MID$(STR$(i + 1), 2), 2); "   ";
  341.              LINE (16 + i * 40, 335 * YfacTXT)-(40 + i * 40, 349 * YfacTXT), i + 1, BF
  342.          NEXT i
  343.          GOSUB BoxLine23
  344.          INPUT "Select color (4,7,10-Hwys 11-Water 12-Hwy 13-Spcl 14-City)"; B$
  345.          SavClr = VAL(B$): IF SavClr > 15 OR SavClr < 1 THEN abort = -1 ELSE abort = 0
  346.          RETURN
  347.  
  348.            
  349. BeginF: x%(nmp) = 0: y%(nmp) = SavClr   'Store feature color 0,c
  350.         LN$(LNi + 1) = LN$(LNi): LnPtr = LNi'Bump up present LN$ comment
  351.         LN$(LNi) = a$: LNi = LNi + 1'Store feature name
  352.         nmp = nmp + 1: Z = nmp
  353.         nmp = nmp + 1: x%(nmp) = 0: y%(nmp) = 0'nmp points to ending 0,0
  354.         RETURN
  355.  
  356. CanclF: nmp = nmp - 2: Z = Kz
  357.         LNi = LNi - 1: LN$(LNi) = LN$(LNi + 1): RETURN
  358.  
  359. NewCenter: LATcen = CPY: LONcen = CPX: Changed = Changed + 1: GOTO CurDrwMap
  360.  
  361. MapRange: GOSUB BoxLine23: INPUT "Enter map range"; a$
  362.           IF VAL(a$) <> 0 THEN MapRng = VAL(a$)
  363.           Changed = Changed + 1: GOTO DrwMPaCur
  364.  
  365. AddPoint: x% = dx + (CUX - 320) / (KP * Hfac)
  366.           IF x% = 0 THEN BEEP: PRINT "X=0!!!": RETURN
  367.           nmp = nmp + 1: Z = Z + 1
  368.           FOR i = nmp TO Z STEP -1
  369.               x%(i) = x%(i - 1): y%(i) = y%(i - 1)
  370.           NEXT
  371.           GOSUB MakePT
  372.           IF SavClr = 0 AND ReDraw THEN GOTO DrawMap
  373.           s = Z - 1: LineColor = SavClr: GOTO DP
  374.  
  375. MakePT: x%(Z) = dx + (CUX - 320) / (KP * Hfac)
  376.         y%(Z) = dy + (CUY - Ycen) / KP
  377.         Changed = Changed + 1
  378.         GOTO MapPoint
  379.  
  380. CurToPoint:
  381.      CPX = CDX - (x%(Z) - dx) / ppdV
  382.      CPY = CDY - (y%(Z) - dy) / (ppdV * Yfactr)
  383.      GOTO Cursor
  384.  
  385. DelPT: GOSUB DelZ
  386.        REM if 1st pt, it stays as 1st pt
  387.  
  388.        IF x%(Z) = 0 THEN Z = Z - 1: REM if end pt, it stays as end
  389.        IF x%(Z + 1) = 0 AND x%(Z - 1) = 0 THEN 'It is LAST point
  390.           GOSUB Kline: LnPtr = LnPtr - 1       'So Kill Line
  391.           GOSUB DelZ                           'And Kiil it
  392.           Z = Z - 1: GOSUB DelZ: Z = Z - 1     'Kill 0,color
  393.        END IF                                  'and -1 to end point
  394.        IF B$ = CHR$(32) AND ReDraw THEN GOSUB DrawMap ELSE GOSUB MapPoint
  395.        RETURN
  396.  
  397. DelZ: nmp = nmp - 1
  398.       FOR i = Z TO nmp
  399.           x%(i) = x%(i + 1): y%(i) = y%(i + 1)
  400.       NEXT: Changed = Changed + 1: RETURN
  401.  
  402. NextLine: IF Z >= nmp - 1 THEN Z = nmp - 1: BEEP: RETURN
  403.           DO UNTIL x%(Z) = 0: Z = Z + 1: LOOP
  404.           IF Z < nmp - 1 THEN Z = Z + 1: LnPtr = LnPtr + 1
  405.           SavClr = 0: GOTO MapPoint
  406. Previous: DO UNTIL Z = 1 OR x%(Z) = 0: Z = Z - 1: LOOP
  407.           IF Z > 3 THEN Z = Z - 1: LnPtr = LnPtr - 1
  408.           SavClr = 0: GOTO MapPoint
  409.  
  410. KillF: GOSUB Find1st: REM Stop at Beginning (0) point of the feature to kill
  411.        ni = Bi + 1' Now scan for next feature
  412.        DO UNTIL x%(ni) = 0: ni = ni + 1: LOOP
  413.        REM now move down rest of array to fill
  414.        DO UNTIL ni = nmp + 1
  415.            x%(Bi) = x%(ni): y%(Bi) = y%(ni)
  416.            Bi = Bi + 1: ni = ni + 1
  417.        LOOP
  418.        nmp = nmp - (ni - Bi): y%(nmp) = 0
  419.        GOSUB Kline
  420.        GOTO DrawMap
  421.     
  422. Find1st: Bi = Z: Changed = Changed + 1
  423.          DO UNTIL x%(Bi) = 0: Bi = Bi - 1: LOOP: Z = Bi + 1
  424.          RETURN
  425.  
  426. ChgColr: GOSUB Find1st: GOSUB Rainbow: IF abort THEN RETURN
  427.          y%(Bi) = SavClr: RETURN
  428.  
  429.  
  430. Kline: FOR i = LnPtr TO LNi
  431.            LN$(i) = LN$(i + 1)
  432.            NEXT i
  433.            LNi = LNi - 1
  434.            RETURN
  435.  
  436. MapPoint:
  437.      IF Z < 2 THEN Z = 2: LnPtr = 1: BEEP: SavClr = 0
  438.      IF Z > nmp - 1 THEN Z = Z - 1: BEEP: SavClr = 0
  439.      IF x%(Z) = 0 THEN
  440.         IF a$ = "-" THEN
  441.              LnPtr = LnPtr - 1: Z = Z - 1
  442.         ELSE LnPtr = LnPtr + 1: Z = Z + 1
  443.         END IF: SavClr = 0
  444.      END IF
  445.      IF LnPtr < 0 THEN LnPtr = 0
  446.      IF Display$ = "MAP" THEN
  447.           LOCATE 22, 1
  448.           PRINT "Fture#"; LnPtr; TAB(12); LEFT$(LN$(LnPtr) + "            ", 12);
  449.      END IF
  450. DrwMpPt: IF Display$ <> "MAP" THEN RETURN
  451.      CIRCLE (Xtest, Ytest), 10, 0 'Erase old circle
  452.      Xtest = 320 + KP * (x%(Z) - dx) * Hfac
  453.      Ytest = Ycen + KP * (y%(Z) - dy) * Yfactr
  454.      CIRCLE (Xtest, Ytest), 10, 15
  455.      
  456.      LOCATE 23, 1: PRINT "MapPt#"; Z;
  457.      IF Z > 999 THEN PRINT TAB(13); "val:";  ELSE PRINT TAB(12); "vals:";
  458.      PRINT TAB(17); x%(Z); TAB(23); y%(Z)
  459.      RETURN
  460.  
  461. AddLabel: nml = nml + 1
  462.           MLa(nml) = CPY: MLo(nml) = CPX
  463.           GOSUB BoxLine23: INPUT "Enter Label Name"; a$: ML$(nml) = a$
  464.           GOSUB BoxLine23: INPUT "Begin displaying label at what range?"; a$
  465.           a = VAL(a$): IF a <> 0 THEN MLr(nml) = a:  ELSE MLr(nml) = 2048
  466.           Changed = Changed + 1: GOTO labels
  467.  
  468. BoxLine23: LOCATE 23, 1: PRINT SPACE$(80); : LOCATE 23, 1: RETURN
  469.  
  470. ErrorTrap: Fault = ERR: 'Error handling routine
  471.            IF ERR = 57 THEN PRINT "  I/O-error-User-logoff"; : RESUME
  472.            IF ERR = 69 THEN PRINT "  Comm-buffer-overflow"; : RESUME
  473.            IF ERR = 53 THEN PRINT "  file-"; F$; "-not-found": CLOSE : RESUME NEXT
  474.            IF ERR = 62 THEN RESUME NEXT
  475.            IF ERR = 52 THEN RESUME NEXT
  476.            IF ERR = 55 THEN RESUME NEXT
  477.            IF ERR = 2 THEN PRINT "SYNTAX-error"
  478.            IF ERR = 70 THEN PRINT " WRITE PROTECTED!...": RESUME NEXT
  479.            IF ERR = 76 THEN PRINT "Wrong Path!": RESUME NEXT
  480.            IF ERR = 71 THEN PRINT "no disk!": RESUME NEXT
  481.            RESET
  482.            PRINT : PRINT "Error beyond repair. Number = "; ERR;
  483.            INPUT "Hit RETURN to return to DOS"; a$
  484.            SYSTEM
  485.  
  486. MapDIR: CLS : PRINT "MAP FILES DIRECTORY": PRINT
  487.          PRINT "To display MAP files, please enter the path to your xxxxxxx.MAP files."
  488.          PRINT "For example, the default '\APRS\MAPS\*.MAP' will show all maps in the APRS"
  489.          PRINT "directory.  Similarly '*.map' will search your present QB directory."
  490.          PRINT "For any other path, enter the full file specification.": PRINT
  491.          F$ = "\aprs\MAPS\*.map"
  492.          PRINT "Enter Filespec for searching the DIRECTORY ("; F$; ")";
  493.          INPUT a$: IF a$ <> "" THEN F$ = a$
  494.          PRINT : PRINT : FILES F$
  495.          RETURN
  496.  
  497.  
  498. LoadMap: 'Maps are drawn to the default EGA resolution of 640 x 400 (350)
  499. Again: GOSUB BoxLine23
  500.        INPUT " Enter map FILENAME, or NEW, or ? for a list, or Q to quit)"; a$
  501.        a$ = UCASE$(a$): IF a$ = "" THEN GOTO Again
  502.        IF a$ = "Q" THEN SYSTEM
  503.        IF a$ = "?" THEN GOSUB MapDIR: GOTO Again
  504.        IF a$ = "NEW" THEN Key$ = "NEW": GOSUB NewMap: RETURN
  505.        a = INSTR(3, a$, "."): IF a = 0 THEN a$ = a$ + ".MAP"
  506.        MapFile$ = a$: F$ = MapFile$: OPEN F$ FOR INPUT AS #3
  507.        IF Fault = 53 THEN Fault = 0: PRINT : CLOSE #3: GOTO Again
  508.        GOSUB BoxLine23: PRINT " Loading "; F$; "..."
  509.        INPUT #3, LATo: LINE INPUT #3, LATtext$
  510.        INPUT #3, LONo: LINE INPUT #3, LONtext$
  511.        INPUT #3, ppdV: LINE INPUT #3, VS$'Pixels per degree horiz
  512.        INPUT #3, LATcen: LINE INPUT #3, LATcen$
  513.        INPUT #3, LONcen: LINE INPUT #3, LONcen$
  514.        INPUT #3, MapRng: LINE INPUT #3, MapRng$
  515.        INPUT #3, MinRng: LINE INPUT #3, MR$
  516.        LINE INPUT #3, TextLine$ ' Line of comments or instrutcitons
  517.        IF LEFT$(TextLine$, 14) = "Map generated " THEN ReDraw = 0
  518.        RS = 2 ^ INT(LOG(MapRng) / LOG(2))'Rng is intgr of VERTrng
  519.        i = 0: LNi = 0:
  520.      
  521.      DO WHILE NOT EOF(3)
  522.         i = i + 1: INPUT #3, x%(i), y: y%(i) = y * Yfactr
  523.         IF x%(i) = 0 AND NOT EOF(3) THEN ' Get line color & store with x=0
  524.            INPUT #3, y%(i): LNi = LNi + 1: LINE INPUT #3, LN$(LNi)' Save line name
  525.            IF y = -1 THEN GOSUB LoadLabels ' All labels listed at end of file
  526.            END IF
  527.         LOOP: nmp = i  'nmp points to 0,-1 that ends all data (but the value
  528.                        'of X% and y% are 0,0 until file is saved.
  529.      LET CDY = LATcen: CDX = LONcen'Center display on ORIGIN
  530.      LET CPX = CDX: CPY = CDY 'Cursor Posn to Center of Display
  531.      LET Z = 2: LnPtr = 1: REM start at first point and first line segment
  532.      CLOSE #3: RETURN:     REM first X% value is map color.  2nd val is 1st pt
  533.  
  534.  
  535.  
  536. LoadLabels: K = 0
  537.      DO WHILE NOT EOF(3)
  538.         K = K + 1: INPUT #3, ML$(K), MLa(K), MLo(K), MLr(K)
  539.      LOOP
  540.      IF MLa(K) = 0 OR MLo(K) = 0 THEN nml = K - 1 ELSE nml = K
  541.      RETURN
  542.        
  543. SaveMap: GOSUB BoxLine23
  544.    PRINT "Enter file name to save if other than "; MapFile$;
  545.    INPUT a$: IF a$ <> "" THEN MapFile$ = a$
  546.    F$ = MapFile$
  547.    GOSUB BoxLine23: PRINT "Saving map to file named "; F$; " ..."
  548.    OPEN F$ FOR OUTPUT AS #4
  549.    IF Fault = 70 OR Fault = 71 THEN Fault = 0: CLOSE #4: GOTO SaveMap
  550.    PRINT #4, LATo; ","; LATtext$
  551.    PRINT #4, LONo; ","; LONtext$
  552.    PRINT #4, ppdV; ","; VS$
  553.    PRINT #4, LATcen; ","; LATcen$
  554.    PRINT #4, LONcen; ","; LONcen$
  555.    PRINT #4, MapRng; ","; MapRng$
  556.    PRINT #4, MinRng; ","; MR$
  557.    PRINT #4, TextLine$
  558.    j = 1
  559.    FOR i = 1 TO nmp
  560.        IF x%(i) <> 0 THEN WRITE #4, x%(i), INT((y%(i) / Yfactr) + .5)
  561.        IF x%(i) = 0 AND i = nmp THEN PRINT #4, " 0,-1"
  562.        IF x%(i) = 0 AND i <> nmp THEN
  563.           PRINT #4, "0,0"
  564.           PRINT #4, y%(i); ","; LN$(j): j = j + 1
  565.        END IF
  566.    NEXT i
  567.    PRINT #4, "0,"; LN$(LNi)
  568.    FOR K = 1 TO nml
  569.        PRINT #4, ML$(K); ","; : WRITE #4, MLa(K), MLo(K), MLr(K)
  570.    NEXT K: CLOSE #4: LOCATE 24, 1:
  571.    Changed = 0
  572.    IF nmp > MaxNumPoints OR nml > MaxNumLABELS THEN
  573.       CLS : LOCATE 9, 29: PRINT "CAUTION!": PRINT : PRINT
  574.       IF nmp > MaxNumPoints THEN
  575.          PRINT "            The number of points,"; nmp; "is greater than"; MaxNumPoints
  576.       END IF
  577.       IF nml > MaxNumLABELS THEN
  578.          PRINT "            The number of LABELS,"; nml; "is greater than"; MaxNumLABELS
  579.       END IF
  580.       LOCATE 18, 12
  581.       PRINT " Therefore this map will not work with APRS (yet) "
  582.       LOCATE 23, 1: INPUT "HIT Enter to continue..."; a$
  583.    END IF: GOTO DrwMPaCur
  584.  
  585. CurDrwMap: CDX = CPX: CDY = CPY: GOTO DrawMap: REM Re-center at CURSOR location
  586.  
  587. DrwMPaCur: CPX = CDX: CPY = CDY: GOSUB DrawMap
  588.            REM After drawing map, Put cursor at center
  589.            RETURN
  590.  
  591. DrawMap: IF USGS THEN RETURN
  592.     Display$ = "MAP": COLOR 15, 0
  593.    'Draw to range scale RS and center display CDX and CDY
  594.    'Original Map was 40 pix-per-deg Horiz and 20 vert for 200 display
  595.    'Now ppdH and ppdV are variables.  The scaling factor KP is 1 for
  596.    'the original map scale.
  597.    DO WHILE RS < 320 / ppdV: RS = RS * 2: LOOP
  598.    IF RS > 8192 THEN RS = 8192
  599.    KP = 100 * 100 / (RS * ppdV)'This is to scale it down from the 120 maps
  600.    Sfac = 50 * 200 / RS        'Till 307 had been 100*120
  601.  
  602.    Lfac = COS(CDY / 57.296)
  603.    Hfac = (640 / 350) * (3 / 4) * Lfac
  604.    dx = ppdV * (LONo - CDX)
  605.    dy = ppdV * (LATo - CDY)
  606.         
  607.    CLS : LOCATE 1, 2: PRINT "Redrawing Map"
  608.    REM first put ORIGIN and map CENTER on the map
  609.    LINE (320 - KP * dx, Ycen - KP * dy)-(960 - KP * dx, Ycen - KP * dy), 14
  610.    LINE (320 - KP * dx, Ycen - KP * dy)-(320 - KP * dx, 3 * Ycen - KP * dy), 14
  611.    CMX = 320 + Sfac * (CDX - LONcen) * Hfac'new
  612.    CMY = Ycen + Sfac * (CDY - LATcen) * Yfactr
  613.    LINE (CMX - 27, CMY)-(CMX + 27, CMY), 14
  614.    LINE (CMX, CMY - 20)-(CMX, CMY + 20), 14
  615.    CIRCLE (CMX, CMY), 10, 14
  616.    CIRCLE (320 - KP * dx, Ycen - KP * dy), 12, 14
  617.    s = 0: GOSUB MapPoint: REM Redraw MapPoint
  618.    StrtPt = -1
  619. DP: FOR i = s TO nmp - 1
  620.        x = 320 + KP * (x%(i) - dx) * Hfac
  621.        y = Ycen + KP * (y%(i) - dy) * Yfactr
  622.        X1 = 320 + KP * (x%(i + 1) - dx) * Hfac
  623.        Y1 = Ycen + KP * (y%(i + 1) - dy) * Yfactr
  624.        IF StrtPt = -1 THEN CIRCLE (x, y), 3, 9: StrtPt = 0
  625.        IF x%(i + 1) <> 0 THEN
  626.           IF RdsOn OR LineColor <> 12 THEN LINE (x, y)-(X1, Y1), LineColor
  627.           IF i = Z THEN SavClr = LineColor
  628.        ELSE
  629.           REM LINE (x - 3, y - 3)-(x + 3, y + 3), 10, B: StrtPt = -1
  630.           CIRCLE (x, y), 5, 10: StrtPt = -1
  631.           LineColor = y%(i + 1): i = i + 1
  632.           IF Display$ = "SHOW" AND LineColor > 8 THEN LineColor = LineColor - 8
  633.        END IF
  634.    NEXT i
  635.    GOSUB Cursor
  636.    GOSUB ReDraw
  637.    REM MapPoint went here
  638.    GOSUB DrawHist: REM draw GPS history track
  639.    IF Display$ = "SHOW" THEN
  640.       GOSUB ShowMaps
  641.    ELSE
  642.       LOCATE 25, 1: PRINT "Use +/- to move MAPpoint.  N/P for Next/Previous Feature.  H for HELP!.";
  643.       LOCATE 1, 61
  644.       PRINT "POINTS"; nmp; "= "; INT((nmp / MaxNumPoints) * 100); "%";
  645.       LOCATE 2, 61
  646.       PRINT "LABELS "; nml; "= "; INT((nml / MaxNumLABELS) * 100); "%";
  647.       LOCATE 3, 61: PRINT "CENTER  "; MID$(STR$(LATcen), 2, 5);
  648.       LOCATE 3, 75: PRINT MID$(STR$(LONcen), 2, 5)
  649.       LOCATE 4, 61: PRINT "SCALE   (ppd)"; ppdV
  650.       LOCATE 5, 69: PRINT "Range"; LEFT$(STR$(MapRng), 5)
  651.    END IF
  652.  
  653. labels:
  654.    IF Labls THEN
  655.       FOR i = 1 TO nml ' Now plot labels on map
  656.       IF RS <= MLr(i) OR Key$ = "S" THEN
  657.          LET x = 320 + Sfac * (CDX - MLo(i)) * Hfac'new
  658.          LET y = Ycen + Sfac * (CDY - MLa(i)) * Yfactr
  659.          IF Tags AND y > 14 * Yfactr AND y < 350 * Yfactr AND x > 8 * (LEN(ML$(i)) + 1) AND x < 632 THEN
  660.             LOCATE y / (14 * Yfactr), (x / 8) - LEN(ML$(i)): PRINT ML$(i);
  661.             END IF
  662.          END IF
  663.       NEXT i
  664.    END IF
  665.    GOSUB ShowMap: RETURN
  666.          
  667. ShowMap: REM this shows the map boarder of the loaded map
  668.     x = 320 + KP * (CDX - LONcen) * ppdV * Hfac'new
  669.     y = Ycen + KP * (CDY - LATcen) * ppdV * Yfactr
  670.       by = MapRng * Sfac * Yfactr / 60
  671.       bx = by * 640 / (400 * Yfactr) * Lfac'old
  672.       C = 15
  673.     LINE (x - bx, y - by)-(x + bx, y + by), C, B
  674.     RETURN
  675.  
  676. Cursor: CIRCLE (CUX, CUY), 4, 0
  677.      CUX = 320 + Sfac * (CDX - CPX) * Hfac'new
  678.      CUY = Ycen + Sfac * (CDY - CPY) * Yfactr
  679.      CIRCLE (CUX, CUY), 4, 14
  680.      IF CPX > 0 THEN
  681.           x = INT(CPX): Xm = (CPX - x) * 60
  682.      ELSE x = INT(-CPX): Xm = -(CPX + x) * 60
  683.      END IF
  684.      IF CPY > 0 THEN
  685.           y = INT(CPY): Ym = (CPY - y) * 60
  686.      ELSE y = INT(-CPY): Ym = -(CPY + y) * 60
  687.      END IF
  688.      x$ = RIGHT$(STR$(x), 3) + " "
  689.      LOCATE 1, 2: PRINT "RNG"; RIGHT$("   " + STR$(RS), 4) + "      "
  690.      LOCATE 2, 2: PRINT "LAT "; y; MID$(STR$(Ym) + "   ", 2, 5)
  691.      LOCATE 3, 2: PRINT "LON "; x$; MID$(STR$(Xm) + "   ", 2, 5)
  692.     
  693.      LOCATE 24, 1: PRINT "Cursor coordnts:"; TAB(17);
  694.      PRINT INT(.5 + dx + (CUX - 320) / KP); TAB(23); INT(.5 + dy + (CUY - Ycen) / KP);
  695.      REM LOCATE 24, 55: PRINT "Degrees: ";
  696.      REM PRINT LEFT$(STR$(CPY) + " ", 7); LEFT$(STR$(CPX) + "   ", 7);
  697.      LOCATE 1, 16: PRINT "Decimal";
  698.      LOCATE 2, 15: PRINT LEFT$(STR$(CPY) + " ", 8);
  699.      LOCATE 3, 15: PRINT LEFT$(STR$(CPX) + "   ", 8);
  700.      LINE (0, 0)-(178, 42 * Yfactr), 12, B'Box around it
  701.      LINE (0, 0)-(116, 42 * Yfactr), 12, B'Box around it
  702.      LET a$ = "": LET B$ = "": RETURN
  703.  
  704. HELP: CLS : COLOR 15, 1: LINE (0, 0)-(639, 18 * Yfactr), 14, BF
  705.       LOCATE 1, 20: PRINT " MAPFIX.bas HELP SCREEN Ver "; Ver$
  706.       LOCATE 3, 1
  707.       
  708.       PRINT " The cursor is shown in LAT/LON, map offset and decimal degrees.   The ORIGIN,"
  709.       PRINT " CENTER and BORDER are shown (but only the CENTER and RANGE in MAPLIST.map are"
  710.       PRINT " actually used by APRS.  Labels are right justified to the point just after the"
  711.       PRINT " last letter.  CALLS & OBJECT names will be left justified."
  712.       PRINT ""
  713.       PRINT " OPERATIONS          MAP FUNCTIONS         @N - NEW FEATURE   LABEL COMMANDS"
  714.       PRINT " H - HELP SCREENS    @C- Change CENTER     @A - ADD point      S - SHOW labels"
  715.       PRINT " D - map DIRECTORY   ^C- Change COLOR      @D - DELETE point  @L - add a LABEL"
  716.       PRINT "^S - SAVE MAP!!!     M - MAPLIST.apr file  @K - Kill feature   L - LABELS off"
  717.       PRINT " R - RESET pointers  O - OTHER map bordrs  @M - MOVE point"
  718.       PRINT " Q - QUIT            @R- set map RANGE     @T - TRIM borders"
  719.       PRINT "                                               "
  720.       PRINT " MAP COMMANDS        POINTER MOVEMENTS   USGS CD ROM CMDS   DIGITIZER & GPS "
  721.       PRINT " SPACE to draw map   N - Next Feature    B - BOX PPD area   @O- OPEN COMMS"
  722.       PRINT " ARROWS  (shft)      P - Prev Feature    U - USGS overlay   @B- BEGIN new line"
  723.       PRINT " PgUP/DN (ctrl)      G - Go to Pointer   T - Test smoother "
  724.       PRINT " HOME to Cursor      F - Find point      @S- SMOOTH file"
  725.       PRINT " END to map center   ^F- Find another    @U- USGS BUILD!    @G- GPS OVERLAY"
  726.       PRINT "                     +/- move Pointer    @J- JOIN lines"
  727.       PRINT "                                         ^R- REDRAW on/off"
  728.       PRINT : LINE (0, 190 * Yfactr)-(639, 190 * Yfactr), 15
  729.               
  730.       IF Display$ <> "HELP" THEN
  731.        LOCATE 25, 1
  732.        PRINT " HIT H AGAIN FOR MORE HELP SCREENS, OR SPACE BAR FOR MAP...";
  733.       END IF
  734.       Display$ = "HELP"
  735.       LINE (0, 0)-(634, 348 * Yfactr), 15, B
  736.       RETURN
  737.  
  738.  
  739.  
  740. REM ************* HERE IS THE CODE BROUGHT IN FROM APRS  ***************
  741.  
  742. LdMapLst: GOSUB BoxLine23: INPUT "FileSpec for MAPLIST.apr if not \APRS\MAPLIST.APR"; a$
  743.           IF a$ <> "" THEN F$ = a$ ELSE F$ = "\aprs\Maplist.apr"
  744.           OPEN F$ FOR INPUT AS #3: IF Fault <> 0 THEN RETURN
  745.           i = 1: NumGood = 0
  746.           INPUT #3, DfltY: LINE INPUT #3, a$
  747.           INPUT #3, DfltX: LINE INPUT #3, a$
  748.           INPUT #3, BestRng: LINE INPUT #3, a$: DfltR = BestRng
  749.           INPUT #3, GMToffset: LINE INPUT #3, a$
  750.     WHILE a$ <> "* BEGIN *": LINE INPUT #3, a$: WEND ' Skip comment block
  751.           REM RS = BestRng: REM center display
  752.           REM RS = 2 ^ INT(LOG(RS) / LOG(2))'Rng is intgr power of 2
  753.           REM CPX = CDX: CPY = CDY 'Cursor Posn to Center of Display
  754.     WHILE NOT EOF(3) AND i <= UBOUND(MapName$)
  755.           INPUT #3, MapName$(i), LATcen(i), LONcen(i), MapMax(i)
  756.           LINE INPUT #3, Comment$(i)' IGNORE ALL comment fields
  757.           REM now ignore maps that start with a *
  758.           IF LEFT$(MapName$(i), 1) <> "*" THEN NumGood = NumGood + 1
  759.           NumMaps = i: i = i + 1
  760.     WEND: CLOSE #3
  761.     IF NumGood >= MaxNumMAPS - 1 THEN
  762.           CLS : LOCATE 2, 5
  763.           PRINT "WARNING: Too many ACTIVE MAPS (more than"; MaxNumMAPS; ") in MAPLIST.map file for APRS"
  764.           LOCATE 4, 10: PRINT "Use EDITOR to suppress mapnames with an (*) that you don't need."
  765.           PRINT : PRINT : PRINT : MapListLoaded = -1
  766.           INPUT "HIT RETURN to continue"; a$
  767.     END IF
  768.     RETURN
  769.  
  770. ListMAPlist: IF NOT MapListLoaded THEN GOSUB LdMapLst
  771.    GOSUB ListHeader
  772.    FOR i = 1 TO NumMaps
  773.        IF i / 19 = INT(i / 19) THEN
  774.           LOCATE 25, 1: PRINT "HIT RETURN to continue"; : INPUT a$
  775.           GOSUB ListHeader
  776.        END IF
  777.        PRINT MapName$(i); TAB(14);
  778.        PRINT INT(LATcen(i) * 100) / 100; TAB(21); INT(LONcen(i) * 100) / 100;
  779.        PRINT TAB(29); MapMax(i); TAB(36); LEFT$(LTRIM$(Comment$(i)), 43)
  780.    NEXT i
  781.    
  782.    LOCATE 25, 1: PRINT "LIST COMPLETE. CONTINUE WITH NEXT MAPFIX COMMAND...";
  783.    RETURN
  784.  
  785. ListHeader: CLS
  786.    PRINT "MAPS in MAPLIST.map (*MAPS are suppressed)     [For now, use EDITOR to modify]"
  787.    PRINT :
  788.    PRINT "MAP NAME      LATcen LONcen  RANGE COmments"
  789.    PRINT "------------  ------ ------- ----- -------------------------------------------"
  790.    RETURN
  791.  
  792. DrwAndShow: IF NOT MapListLoaded THEN GOSUB LdMapLst
  793.             Display$ = "SHOW": GOSUB DrwMPaCur
  794.  
  795. ShowMaps: IF MapSize > RS / 2 THEN MapSize = RS / 2
  796.     LOCATE 25, 1: PRINT " Drawing all maps >"; MapSize;
  797.     PRINT "mi.  F3 to see smaller, F4 for bigger, SPACE to cancel.";
  798.     LINE (0, 336 * Yfactr)-(639, 349 * Yfactr), 14, B
  799.     FOR i = 1 TO NumMaps
  800.    
  801.     x = 320 + Sfac * (CDX - LONcen(i)) * Hfac
  802.     y = Ycen + Sfac * (CDY - LATcen(i)) * Yfactr
  803.       dy = MapMax(i) * Sfac * Yfactr / 60
  804.       dx = dy * 640 / (400 * Yfactr) * Lfac
  805.       C = 15
  806.       IF MapMax(i) > 32 THEN C = 14
  807.       IF MapMax(i) > 64 THEN C = 12
  808.       IF MapMax(i) > 128 THEN C = 11
  809.       IF MapMax(i) > 256 THEN C = 13
  810.           
  811.     IF MapMax(i) > MapSize THEN
  812.        LINE (x - dx, y - dy)-(x + dx, y + dy), C, B
  813.        IF y + dy > 14 * Yfactr AND y + dy < 350 * Yfactr THEN
  814.           IF x + dx > 8 * (LEN(MapName$(i)) + 1) AND x + dx < 632 THEN
  815.              LOCATE (y + dy) / (14 * Yfactr), (x + dx) / 8 - LEN(MapName$(i))
  816.              IF MapMax(i) > RS / 4 THEN PRINT MapName$(i);
  817.           END IF
  818.        END IF
  819.     END IF
  820.     NEXT i: RETURN
  821.         
  822. REM ******* here is the code added by W7KKE for overlyaying track histoiries
  823. 'This module retrieves GPS history files so you can check the accuracy of
  824. 'the map
  825.  
  826. Hstdir: CLS : PRINT "HISTORY FILES DIRECTORY": PRINT
  827.          PRINT "To display HST files, please enter the path to your xxxxxxx.HST files."
  828.          PRINT "For example, the default '\APRS\*.HST' will show all maps in the APRS"
  829.          PRINT "directory.  Similarly '*.hst' will search your present QBasic directory."
  830.          PRINT "For any other path, enter the full file specification.": PRINT
  831.          
  832.          PRINT "Enter Filespec for searching the DIRECTORY (\aprs\*.hst)";
  833.          INPUT F$: IF F$ = "" THEN F$ = "\aprs\*.hst"
  834.          IF INSTR(F$, ".") = 0 THEN F$ = F$ + ".HST"
  835.          PRINT : PRINT : FILES F$
  836.          RETURN
  837.  
  838. LoadHst: GOSUB BoxLine23
  839.        INPUT "Which history file to load (ENTER for list, Q to quit)"; F$
  840.        IF UCASE$(F$) = "Q" THEN RETURN
  841.        IF F$ = "" THEN GOSUB Hstdir: GOTO LoadHst
  842.        a = INSTR(3, F$, "."): IF a = 0 THEN F$ = F$ + ".hst"
  843.        Fault = 0: F$ = UCASE$(F$): OPEN F$ FOR INPUT AS #3
  844.    
  845.        IF Fault = 53 OR Fault = 62 THEN Fault = 0: RETURN
  846.        GOSUB BoxLine23: PRINT "Loading track history from "; F$
  847.        
  848.     DO WHILE NOT EOF(3)
  849.        i = i + 1
  850.        INPUT #3, a$
  851.        HLAT(i) = VAL(MID$(a$, 26, 2)) + (VAL(MID$(a$, 28, 5)) / 60)
  852.        HLONG(i) = VAL(MID$(a$, 35, 3)) + (VAL(MID$(a$, 38, 5)) / 60)
  853.        maxhist = i
  854.      LOOP
  855.      CLOSE #3: Histloaded = -1
  856.      GOSUB BoxLine23: PRINT "File loading is complete.  GPS data is plotted."
  857.      REM fall through...
  858.  
  859. DrawHist:  'put history track on map
  860.      IF Histloaded THEN
  861.         size = 3: IF RS < 2 THEN size = size * 2 / RS
  862.         FOR i = 1 TO maxhist
  863.             HMX = 320 + KP * (CDX - HLONG(i)) * ppdV * Hfac'new
  864.             HMY = Ycen + KP * (CDY - HLAT(i)) * ppdV * Yfactr
  865.             CIRCLE (HMX, HMY), size, 13
  866.         NEXT i
  867.      END IF
  868.      RETURN
  869.  
  870. NewMap: CLS : PRINT "BEGINNING A NEW MAP FROM SCRATCH...": PRINT
  871.    PRINT "All points in an APRS map are measured as an"
  872.    PRINT "offset to the right and down from an origin."
  873.    PRINT
  874.    INPUT "Enter the LATITUDE  of the ORIGIN in degrees , minutes (DD, mm.xx)"; LATo, LAm
  875.    INPUT "Enter the LONGITUDE of the ORIGIN in degrees , minutes (DDD, mm.xx)"; LONo, LOm
  876.    LATo = LATo + LAm / 60
  877.    LONo = LONo + LOm / 60
  878.    PRINT
  879.    PRINT "Choose the number of pixels per degree to set the map scale:"
  880.    PRINT
  881.    PRINT "Approximate size    Range from center  Pixels/Deg"
  882.    PRINT "----------------    -----------------  ----------"
  883.    PRINT "Big state or region        250             120"
  884.    PRINT "Typical state              100             300"
  885.    PRINT "Several Counties            50             600"
  886.    PRINT "Typical VHF range           25            1200"
  887.    PRINT "City streets (7.5 min maps) 12            2400"
  888.    PRINT
  889.    INPUT "Enter desired Pixels/Deg"; ppdB
  890.    IF ppdB = 0 THEN GOTO NewMap
  891.    REM In following lines, 500 is half of 999 (maximum nominal value for pts)
  892.    LATcen = LATo - (500 * Yfactr / ppdB)
  893.    LONcen = LONo - (500 / ppdB)
  894.    GOSUB StartMap: ppdV = ppdB
  895.    CLS : PRINT "YOU ARE NOW READY TO DRAW A NEW MAP...": PRINT : PRINT
  896.    PRINT "A white border has been drawn around the maximum size permitted for this map"
  897.    PRINT
  898.    PRINT "USING CURSOR WITHOUT DIGITIZER:  Move coursor to starting point for a NEW"
  899.    PRINT "feature and hit ALT-N.  Then enter new feature name (for reference purposes)"
  900.    PRINT "and continue moving cursor to the next point and hit ALT-A to add more points."
  901.    PRINT "Continue in this fashion, using ALT-N whenever you want to begin a NEW feature."
  902.    PRINT
  903.    PRINT "USING A DIGITIZER:  First, use ALT-O once to OPEN the digitizer COM port.  Then"
  904.    PRINT "use ALT-B to BEGIN each new map feature.  Enter the name and color of the new"
  905.    PRINT "feature.  Then use the digitizer mouse to add more points."
  906.    PRINT : PRINT : PRINT
  907.    PRINT "Add LABELS on the map at the current cursor location by using the ALT-L key. "
  908.    PRINT
  909.    PRINT "When you are finished, be sure to SAVE the map using the CTRL-S command..."
  910.    PRINT : PRINT : PRINT
  911.    PRINT "FOR HELP, REMEMBER THE  H  KEY!"
  912.    PRINT : PRINT : PRINT "Hit ENTER to proceed..."; : INPUT a$
  913.    RETURN
  914.  
  915. StartMap: REM This called by NEW and in middle of USGS build
  916.    LATcen$ = "LAT of CENTER": LONcen$ = "LON of CENTER"
  917.    MapRng = 60 * 500 * Yfactr / ppdB: REM 500 is half of full map size
  918.    MapRng$ = "Map range from center"
  919.    VS$ = "Pixels per degree"
  920.    MinRng = 1: MR$ = "No longer used"
  921.    TextLine$ = "NEW Map generated by MAPFIX.bas routine..."
  922.    IF Key$ = "NEW" THEN RS = 2 ^ INT(LOG(MapRng) / LOG(2))'Rng is intgr of VERTrng
  923.    CDX = LONcen: CDY = LATcen: CPX = CDX: CPY = CDY
  924.    nmp = 1: nml = 0
  925.    LNi = 1: LN$(1) = "Labels begin here"
  926.    RETURN
  927.  
  928.  
  929. DigiInit: CLS : PRINT : Digitizer = -1
  930.    PRINT "This routine will replace many CURSOR functions with the Digitizer's MOUSE."
  931.    PRINT "Assuming your digitizer can output an X,Y,C format."
  932.    PRINT
  933.    PRINT "Only Mercator projection charts will give absolutely accurate results.  Other"
  934.    PRINT "types, Lambert Conformal, Conical, etc will induce distortions."
  935.    PRINT
  936.    PRINT "It has not been tested with East Longitude or South Latitude."
  937.    PRINT : PRINT
  938.    PRINT "The digitizr should operate at 9600,N,8,1 in POINT mode with 200 LPI resolution."
  939.    PRINT "The FORMAT outputs X,Y,C values separated by commas (C is for button pressed."
  940.    PRINT
  941.    PRINT "Set up the digitizer according to your model's instructions.  For the model"
  942.    PRINT "23360, use the drawing board menu by pressing the mouse button 0 on the SETUP"
  943.    PRINT "label so that the LED is ON.  Then move the mouse to each other label and"
  944.    PRINT "use the 0 button to toggle the value ON or off as follows:"
  945.    PRINT
  946.    PRINT "POINT is ON                             PARITY 7/8 and 1 are ON "
  947.    PRINT "BAUDRATE 3 is ON                        FORMAT is ON ON off ON"
  948.    PRINT "DATA RATE doesn't matter                RESOLUTION off off ON"
  949.    PRINT : PRINT
  950.    INPUT "Is DIGITIZER connected to COM1 or COM2 (1)"; a$
  951.    IF a$ <> "2" THEN a$ = "COM1" ELSE a$ = "COM2"
  952.  
  953.    Port$ = a$ + ":9600,N,8,1,cs0,ds0,cd0"
  954.    OPEN Port$ FOR RANDOM AS #1
  955.    
  956.  
  957.    CLS : PRINT "FIRST LETS TEST THE DIGITIZER, AND GET THE MAP ON STRAIGHT.": PRINT
  958.    PRINT "Move your mouse (or pen) and hit the 0 button (or touch tablet) to see if the"
  959.    PRINT "digitizer is outputting in the desired format.  While doing this, it is a good"
  960.    PRINT "idea to verify that your map is on straight.  The Y values from the mouse"
  961.    PRINT "should give the same values for the same LATITUDE line on both the right and"
  962.    PRINT "left edges of the map.  If not, move your map to get it horizontal."
  963.    PRINT
  964.    PRINT "OUTPUT FORMAT:"
  965.    PRINT
  966.    PRINT "XXXXX,YYYYY,APn (Only the X and Y values are used (4 or 5 digits is ok)"
  967.    PRINT
  968.    LOCATE 25, 1: PRINT "Hit ENTER and press 0 button on mouse to continue...";
  969.    LOCATE 13, 1
  970.    DO UNTIL INKEY$ <> "": LINE INPUT #1, a$: PRINT a$: LOOP
  971.   
  972.    CLS : PRINT
  973.    PRINT "NEXT YOU MUST ESTABLISH THE SCALE OF YOUR DIGITIZER."
  974.    PRINT
  975.    PRINT "The scale is established by two points, the first near the"
  976.    PRINT "upper left corner, the second near the lower right corner."
  977.    PRINT
  978.    PRINT "To get the best accuracy on maps not exactly MERCATOR, use points within the "
  979.    PRINT "area where you are working, not on the extreme corners.  IE:  choose points"
  980.    PRINT "that are in the center of the upper left quadrant and the lower right quadrant."
  981.    PRINT
  982.    PRINT "To establish the upper left reference point:"
  983.    INPUT "     Enter lat  (deg,min)"; LATref1, M: LATref1 = LATref1 + M / 60
  984.    INPUT "     Enter long (deg,min)"; LONref1, M: LONref1 = LONref1 + M / 60
  985.    PRINT
  986.  
  987.    PRINT "Place the mouse on the upper left point and press the 0 button."
  988.    LINE INPUT #1, a$: SOUND 150, 3
  989.         digix1 = 5000 - VAL(LEFT$(a$, 5))
  990.         digiy1 = VAL(MID$(a$, 7, 5))
  991.         PRINT "Digitizer reads "; digix1, digiy1; " for this point.": PRINT
  992.  
  993.    PRINT "NOW Establish the lower right reference point:"
  994.    INPUT "      Enter lat  (deg,min)"; LATref2, M: LATref2 = LATref2 + M / 60
  995.    INPUT "      Enter long (deg,min)"; LONref2, M: LONref2 = LONref2 + M / 60
  996.    PRINT
  997.    PRINT "Place digitizer pen on lower right point."
  998.    LINE INPUT #1, a$: SOUND 150, 3
  999.         digix2 = 5000 - VAL(LEFT$(a$, 5))
  1000.         digiy2 = VAL(MID$(a$, 7, 5))
  1001.         PRINT "Digitizer reads "; digix2, digiy2; " for this point.": PRINT
  1002.  
  1003.    REM Find delta lat/long between reference points
  1004.    REM Calculate degrees per x/y unit
  1005.         degx# = (LONref1 - LONref2) / (digix1 - digix2)
  1006.         degy# = (LATref1 - LATref2) / (digiy1 - digiy2)
  1007.  
  1008.    CLS : PRINT "YOU ARE NOW READY TO USE THE DIGITIZER TO ENTER POINTS INTO MAPFIX..."
  1009.    PRINT
  1010.    PRINT "The digitizer works just about like the cursor and arrow keys in MAPFIX.  Any"
  1011.    PRINT "point identified by the digitizer will be ADDED just as if you had hit ALT-A."
  1012.    PRINT "All points are added to a feature after the current MapPoint identified by the"
  1013.    PRINT "white circle. "
  1014.    PRINT
  1015.    PRINT "With the digitizer, do NOT use the ALT-N NEW command which always begins at the"
  1016.    PRINT "current cursor location.  For the digitizer, use ALT-B to BEGIN a new feature."
  1017.    PRINT "You will be asked to identify the name and color of the new feature.  From then"
  1018.    PRINT "on, just move the digitizer mouse (or pen) to ADD new points.  "
  1019.    PRINT
  1020.    PRINT "If your digitizer mouse has 4 buttons, use the first (left) button for ADDing "
  1021.    PRINT "points, use the 4th (right) button to just move the cursor with no action."
  1022.    PRINT : PRINT
  1023.    INPUT "Hit ENTER to continue with MAPFIX..."; a$
  1024.    RETURN
  1025.  
  1026. GetXY: LINE INPUT #1, a$: SOUND 150, 3
  1027.        a = INSTR(a$, ","): IF a = 0 THEN RETURN
  1028.            x = 5000 - VAL(LEFT$(a$, a - 1))
  1029.        B = INSTR(a + 1, a$, ","): IF B = 0 THEN B = LEN(a$)
  1030.        y = VAL(MID$(a$, a + 1, B - (a)))
  1031.        Btn = VAL(RIGHT$(a$, 1))
  1032.        CPY = ((y - digiy2) * degy#) + LATref2
  1033.        CPX = ((x - digix2) * degx#) + LONref2
  1034.        IF LOC(1) <> 0 THEN a$ = INPUT$(LOC(1), #1)'Clear input buffer
  1035.        RETURN
  1036.  
  1037. BoxPPD: GOSUB BoxLine23: INPUT "Enter the desired PPD"; a$
  1038.    ppdB = VAL(a$)
  1039.    IF ppdB > 1 THEN
  1040.       dy = (30000 / ppdB) * Sfac * Yfactr / 60
  1041.       dx = dy * 640 / (400 * Yfactr) * Lfac
  1042.       GOSUB BoxLine23: LINE (CUX - dx, CUY - dy)-(CUX + dx, CUY + dy), 13, B
  1043.       PRINT "The box represents the largest APRS map that can be made with that scale."
  1044.    END IF
  1045.    RETURN
  1046.         
  1047.  
  1048. GetUSGS: REM This used for both U=OVERLAY and by ALT-U = USGS BUILD!
  1049.    ReDraw = 0: USGS = -1: ni = 0: nt = 0: j = 0: NumLines = 0: LE = 1: OE = 1
  1050.    IF Key$ <> "U" THEN
  1051.       IF ppdB <> 0 THEN ppdV = ppdB
  1052.       IF ppdV < 600 THEN Slope = 1.5 ELSE Slope = 1.2
  1053.       SlopeI = 1 / Slope
  1054.       LATo = CDY + (500 * Yfactr / ppdV)
  1055.       LONo = CDX + (500 / ppdV)
  1056.       GOSUB BoxLine23: PRINT "Improve LAT ORIGIN of "; LATo; : INPUT LATo
  1057.       GOSUB BoxLine23: PRINT "Improve LON ORIGIN of "; LONo; : INPUT LONo
  1058.       GOSUB BoxLine23: INPUT "LATitude extent (100%)"; a$
  1059.             IF a$ <> "" THEN LE = VAL(a$) / 100
  1060.       GOSUB BoxLine23: INPUT "LONgitude extent (100%)"; a$
  1061.             IF a$ <> "" THEN OE = VAL(a$) / 100
  1062.       dx = ppdV * (LONo - CDX)
  1063.       dy = ppdV * (LATo - CDY)
  1064.       KP = 100 * 100 / (RS * ppdV)
  1065.       LATcen = CDY: LONcen = CDX: GOSUB StartMap
  1066.       LATtext$ = "Decimal LATITUDE  of map ORIGIN"
  1067.       LONtext$ = "Decimal LONGITUDE of map ORIGIN"
  1068.       TextLine$ = "Map generated by MAPFIX from USGS 2,000,000:1 CD ROM (data valid mid-1980's)"
  1069.    END IF
  1070.    Lmax = 500 + 600 * LE: Lmin = 500 - 600 * LE 'Max=1100 and Min =-100
  1071.    Omax = 500 + 600 * OE: Omin = 500 - 600 * OE
  1072.    GOSUB BoxLine23: PRINT "Which category (AB,CF,PB,RD,RR,ST,WB) ("; Cat$; ")";
  1073.    INPUT a$
  1074.    IF a$ <> "" THEN
  1075.       a = INSTR(a$, "."): IF a = 0 THEN a$ = a$ + ".GRF"
  1076.       Cat$ = a$
  1077.       GOSUB BoxLine23: PRINT "Enter path and S??_ to USGS file if not "; Path$;
  1078.       INPUT a$
  1079.       IF a$ <> "" THEN Path$ = a$
  1080.       USGS$ = Path$ + Cat$
  1081.    END IF
  1082.    TY$ = UCASE$(LEFT$(Cat$, 2))
  1083.    LowMax = 99: HiMin = 0
  1084.    SELECT CASE TY$
  1085.       CASE "RD", "PB", "AB", "CF", "RR": MaxRnk = 99: MinRNk = 0
  1086.       CASE "WB": MaxRnk = 20: MinRNk = 0: LowMax = 0: HiMin = 5
  1087.       CASE "ST": MaxRnk = 50: MinRNk = 3: LowMax = 16: HiMin = 40
  1088.                ' Does not include canals
  1089.                ' Make minRNK=7 normal, 10 Alaska, 3 alaska for full map
  1090.    END SELECT
  1091.    OPEN USGS$ FOR INPUT AS #3
  1092.    IF Fault <> 0 THEN RETURN
  1093.    REM PRINT "raw data format.....", "   LineID", "#-Rnk-Atbts", "  NumPts"
  1094.    LOCATE 5, 67: PRINT "RANGE: "; INT(30000 / ppdV): LOCATE 24, 1
  1095.    IF Key$ = "U" THEN
  1096.       PRINT "While USGS OVERLAYED, do not redraw map or you will have to do it again...";
  1097.    ELSE PRINT "Blue circles start lines, Green Box ends.  Red points discarded, Yellow Kept!";
  1098.    END IF
  1099.    LOCATE 1, 61: PRINT "TOTAL POINTS: ";
  1100.    LOCATE 2, 61: PRINT "POINTS USED:  ";
  1101.    LOCATE 3, 61: PRINT "TOTAL LINEs:  ";
  1102.    LOCATE 4, 61: PRINT "LINEs USED:   ";
  1103.  
  1104.  DO UNTIL EOF(3) OR LNi = MaxNumLines - 1
  1105.    IF INKEY$ <> "" THEN EXIT DO
  1106.    NumLines = NumLines + 1
  1107.    LOCATE 1, 75: PRINT nt
  1108.    LOCATE 2, 75: PRINT ni
  1109.    LOCATE 3, 75: PRINT NumLines
  1110.    LOCATE 4, 75: PRINT LNi
  1111.    a$ = INPUT$(20, 3): REM PRINT a$;
  1112.         LnID$ = LEFT$(a$, 7)
  1113.         Rank$ = MID$(a$, 8, 2): Rank = VAL(Rank$): LOCATE 6, 67: PRINT "RANK: "; Rank
  1114.         Npts$ = MID$(a$, 10, 6): Npts = VAL(Npts$)
  1115.         AtCd$ = MID$(a$, 16, 5)
  1116.         a$ = LTRIM$(LnID$) + "-" + Rank$ + "-" + AtCd$
  1117.         REM PRINT , LnID$, a$, Npts$
  1118.    IF Rank < 24 THEN SavClr = 4 ELSE SavClr = 7
  1119.    IF Rank < 20 THEN SavClr = 12
  1120.    IF Rank < 14 THEN SavClr = 10
  1121.    LineOK = 0: IF Key$ <> "U" THEN GOSUB BeginF
  1122.    FOR i = 1 TO Npts
  1123.     a$ = INPUT$(20, 3)
  1124.     IF Rank > MaxRnk OR Rank < MinRNk THEN IF Rank > 2 OR TY$ <> "ST" THEN GOTO Skp
  1125.     IF Rank > LowMax AND Rank < HiMin THEN GOTO Skp
  1126.     REM IF VAL(Rank$) > 99 THEN GOTO Skp
  1127.     LA = VAL(LEFT$(a$, 2)) + VAL(MID$(a$, 3, 2)) / 60 + VAL(MID$(a$, 5, 2)) / 3600
  1128.     LO = VAL(MID$(a$, 8, 3)) + VAL(MID$(a$, 11, 2)) / 60 + VAL(MID$(a$, 13, 2)) / 3600
  1129.     IF Key$ = "U" THEN
  1130.         REM Following lines used to limit points if just doing an OVERLAY only
  1131.         IF LA > CDY + RS / 60 OR LA < CDY - RS / 50 THEN GOTO Skp 'off screen
  1132.         IF LO > CDX + RS / (40 * Hfac) OR LO < CDX - RS / (40 * Hfac) THEN GOTO Skp
  1133.         REM s$ = MID$(a$, 16, 5)
  1134.         REM PRINT S$, LA, LO
  1135.         END IF
  1136.     y% = (LATo - LA) * ppdV: x% = (LONo - LO) * ppdV
  1137.     IF Key$ <> "U" AND (x% > Omax OR x% < Omin) THEN GOTO Skp'this ignores points off PPD
  1138.     IF Key$ <> "U" AND (y% > Lmax OR y% < Lmin) THEN GOTO Skp'scale
  1139.     LineOK = -1
  1140.        X1 = 320 + KP * (x% - dx) * Hfac
  1141.        Y1 = Ycen + KP * (y% - dy) * Yfactr
  1142.        IF i > 2 THEN
  1143.           REM LINE (x, y)-(X1, Y1), 6
  1144.           dd = LO - LOb: IF dd = 0 THEN dd = .0000001
  1145.           dn = LA - LAb
  1146.           s = dn / dd' Note that 1>s>.01 for Xdelta of 1 to 100
  1147.           IF ABS(s) < .1 AND ABS(Lsp) < .1 THEN
  1148.              sd = 1
  1149.           ELSEIF ABS(s) > 10 AND ABS(Lsp) > 10 THEN sd = 1
  1150.           ELSEIF ABS(dd) < .004 AND ABS(dn) < .004 THEN sd = 1
  1151.           ELSEIF s <> 0 THEN sd = Lsp / s
  1152.           ELSE sd = 0
  1153.           END IF
  1154.           IF sd > Slope OR sd < SlopeI OR i = Npts THEN
  1155.              PSET (x, y), 14
  1156.              IF Key$ <> "U" THEN GOSUB KeepLine
  1157.           ELSE PSET (x, y), 4
  1158.           END IF
  1159.           Lsp = s: nt = nt + 1
  1160.        ELSE Lsp = 0: CIRCLE (X1, Y1), 2, 9
  1161.           IF Key$ <> "U" THEN GOSUB KeepLine 'keeps first two lines
  1162.        END IF
  1163.        LAb = LA: LOb = LO
  1164.        x = X1: y = Y1
  1165.        
  1166. Skp: NEXT i
  1167.      IF Key$ <> "U" THEN
  1168.         IF LineOK THEN nmp = nmp - 1: Z = Z - 1: ni = ni + 1 ELSE GOSUB CanclF
  1169.      END IF
  1170.      LINE (x - 1, y - 1)-(x + 1, y + 1), 10, B ' Last Point
  1171.  LOOP
  1172.  IF LNi > MaxNumLines - 2 THEN LOCATE 12, 20: PRINT "PROCESSING STOPPED... TOO MANY LLINES!..."
  1173.    CLOSE #3
  1174.    RETURN
  1175.  
  1176. KeepLine: x%(Z) = x%: y%(Z) = y%: nmp = nmp + 1: Z = Z + 1: ni = ni + 1: RETURN
  1177.  
  1178.  
  1179. Scrunch: i = 0: Pt = 0: nt = 0: ni = 0: GOSUB BoxLine23
  1180.     INPUT "Enter slope filter ratio 1.2 to 5 (typically 1.5)"; a$
  1181.     IF a$ = "" THEN Slope = 1.5 ELSE Slope = VAL(a$)
  1182.     DO UNTIL i >= nmp - 1
  1183.        i = i + 1
  1184.        X1 = 320 + KP * (x%(i) - dx) * Hfac
  1185.        Y1 = Ycen + KP * (y%(i) - dy) * Yfactr
  1186.        IF x%(i) <> 0 THEN
  1187.           Pt = Pt + 1
  1188.           IF Pt > 2 THEN
  1189.              LINE (x, y)-(X1, Y1), 6
  1190.              dd = x - X1
  1191.              dn = y - Y1
  1192.              IF dd = 0 AND dn = 0 THEN
  1193.                 sd = Slope: s = Lsp  'Here the points are identical
  1194.                 CIRCLE (x, y), 9, 13
  1195.              ELSE
  1196.                 IF dd = 0 THEN dd = .01
  1197.                 dst = ((dd * dd) + (dn * dn)) ^ .5
  1198.                 s = dn / dd' Note that 1>s>.01 for Xdelta of 1 to 100
  1199.                 IF s = 0 THEN s = .05
  1200.                 IF ABS(s) < .2 THEN s = .2 * SGN(s)
  1201.                 IF ABS(s) > 5 THEN s = 5 * SGN(s)
  1202.                 IF ABS(s) <= .2 AND ABS(Lsp) <= .2 THEN
  1203.                    sd = 1
  1204.                 ELSEIF ABS(s) >= 5 AND ABS(Lsp) >= 5 THEN sd = 1
  1205.                 ELSE sd = Lsp / s
  1206.                 END IF
  1207.                 IF ABS(dd) > 50 * KP OR ABS(dn) > 30 * KP THEN sd = 0
  1208.                 REM IF ABS(dd) < 5 OR ABS(dn) < 4 THEN sd = 1
  1209.              END IF
  1210.              IF sd > Slope OR sd < 1 / Slope OR x%(i + 1) = 0 OR NumRej > 4 THEN
  1211.                 ni = ni + 1: PSET (x, y), 14: NumRej = 0
  1212.                 
  1213.              ELSE PSET (x, y), 4: NumRej = NumRej + 1
  1214.                 IF Key$ <> "T" THEN
  1215.                    i = i - 1: nmp = nmp - 1
  1216.                    FOR ii = i TO nmp
  1217.                        x%(ii) = x%(ii + 1): y%(ii) = y%(ii + 1)
  1218.                    NEXT ii
  1219.                 END IF
  1220.              END IF
  1221.              Lsp = s: nt = nt + 1
  1222.           ELSE Lsp = 0: nt = nt + 1: ni = ni + 1: CIRCLE (X1, Y1), 4, 9
  1223.           END IF
  1224.        ELSE Pt = 0: nt = nt + 1: ni = ni + 1
  1225.           LOCATE 1, 61: PRINT "TOTAL POINTS: "; nt
  1226.           LOCATE 2, 61: PRINT "SAVED POINTS: "; ni
  1227.        END IF
  1228.        x = X1: y = Y1
  1229.     LOOP
  1230.     RETURN
  1231.  
  1232. Join: REM Search for end=begin point values and CONCATONATE if equal!
  1233.    LnPtr = 0: i = 0: K = 0: GOSUB BoxLine23: PRINT "Lines joined: ";
  1234.    DO UNTIL i >= nmp
  1235.       i = i + 1
  1236.        IF x%(i) = x%(i + 2) AND y%(i) = y%(i + 2) AND y%(i + 1) = LColor THEN
  1237.           nmp = nmp - 2: LNi = LNi - 1: K = K + 1: LOCATE 23, 15: PRINT K
  1238.           FOR j = i + 1 TO nmp: x%(j) = x%(j + 2): y%(j) = y%(j + 2): NEXT j
  1239.           FOR j = LnPtr TO LNi: LN$(j) = LN$(j + 1): NEXT j
  1240.        ELSEIF x%(i) = 0 THEN LColor = y%(i): LnPtr = LnPtr + 1
  1241.        END IF
  1242.    LOOP: GOTO DrawMap
  1243.  
  1244. END
  1245.  
  1246.